package jk.framework.canary.core;

import jk.framework.canary.core.engine.CanaryPublishEngine;
import jk.framework.canary.core.engine.DefaultCanaryPublishEngine;
import jk.framework.canary.core.exception.CanaryModuleNotExistException;
import jk.framework.canary.core.mather.DefaultVersionMatcher;
import jk.framework.canary.core.mather.VersionMatcher;
import jk.framework.canary.core.po.RouteContext;
import jk.framework.canary.core.po.CanaryResponse;
import jk.framework.canary.core.repository.VersionInfoRepository;
import jk.framework.canary.core.rule.RouteRuleChain;
import jk.framework.canary.core.version.VersionController;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;



/**
 * @author cuichao
 * 金丝雀发布管理器
 */
public class CanaryMgt {

    private final static Logger logger = LoggerFactory.getLogger(CanaryMgt.class);

    private final static CanaryMgt MGT = new CanaryMgt();

    public static CanaryMgt getInstance(){
        return MGT;
    }

    public static void init(CanaryConfigure configure){
        MGT.configure = configure;
        //按顺序执行
        //初始化控制器
        VersionInfoRepository repository = configure.getVersionInfoRepository();
        if(repository == null){
            throw new CanaryModuleNotExistException(VersionInfoRepository.class + "没有配置该模块的实现类");
        }
        MGT.versionCtl = new VersionController(repository);
        //初始化引擎
        if(configure.getRuleChain() == null){
            throw new CanaryModuleNotExistException(RouteRuleChain.class + "没有配置该模块的实现类");
        }
        MGT.publishEngine = configure.getPublishEngine();

        VersionMatcher matcher = configure.getVersionMatcher() ==  null ?
                new DefaultVersionMatcher() :
                configure.getVersionMatcher();

        if(configure.getPublishEngine() == null){
            matcher= configure.getVersionMatcher() ==  null ?
                            new DefaultVersionMatcher() :
                            configure.getVersionMatcher();
            MGT.publishEngine = new DefaultCanaryPublishEngine(configure.getRuleChain(),matcher);
        }else {
            MGT.publishEngine = configure.getPublishEngine();
        }
        MGT.publishEngine.setVersionCtl(MGT.versionCtl);

        if(logger.isDebugEnabled()){
            logger.debug("VersionMatcher implements is: {}" ,matcher.getClass());
            logger.debug("RouteRuleChain implements is: {}" ,configure.getRuleChain().getClass());
            logger.debug("VersionInfoRepository implements is: {}" ,repository.getClass());
            logger.debug("CanaryPublishEngine implements is: {}" , MGT.publishEngine.getClass());
        }
    }

    public static VersionController getController(){
        return MGT.versionCtl;
    }

    public static <T> CanaryResponse<T> process(RouteContext context, T t){
        return MGT.publishEngine.process(context,t);
    }


    private VersionController versionCtl;

    private CanaryPublishEngine publishEngine;

    private CanaryConfigure configure;

    private CanaryMgt(){
        super();
    }


}
